/***************************************************************************
 *   Copyright (C) 2009 by Jason Power                                     *
 *   power.jg@gmail.com                                                    *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/


#include <QtGui>

#include <openbabel/mol.h>

#include "origindbconvert.h"
#include <molsketch/molecule.h>
#include <molsketch/element.h>
#include <molsketch/molscene.h>

using namespace OpenBabel;
namespace Molsketch {
	OBMol convertToMol(Molsketch::MolScene * scene)
	{
		// Create the output molecule
		OBMol obmol;
		obmol.SetDimension(2);

		// Add all molecules on the scene
		foreach(QGraphicsItem* item, scene->items()) {
		if (item->type() == Molecule::Type) {
			Molecule* mol = static_cast<Molecule*>(item);

			QHash<Atom*,OpenBabel::OBAtom*> hash;

			obmol.BeginModify();
			// creating OBAtoms...
			qDebug() << "Creating OBAtom objects...";
			foreach (Atom* atom, mol->atoms()) {
			OpenBabel::OBAtom* obatom = obmol.NewAtom();
			obatom->SetVector(atom->scenePos().x()/40,atom->scenePos().y()/40,0);
			std::string element = atom->element().toStdString();
			obatom->SetAtomicNum(Molsketch::symbol2number(atom->element()));
			hash.insert(atom,obatom);
			qDebug() << "  " << obatom->GetIdx() << "=" << obatom;
			}

			foreach (Bond* bond, mol->bonds()) {
			Atom* a1 = bond->beginAtom();
			Atom* a2 = bond->endAtom();

			unsigned int beginIdx = hash.value(a1)->GetIdx();
			unsigned int endIdx = hash.value(a2)->GetIdx();
			unsigned int swapIdx = beginIdx;
			int flags = 0;

			// Setting bondtype
			switch (bond->bondType()) {
				case Bond::Wedge:
				flags |= OB_WEDGE_BOND;
				break;
				case Bond::InvertedWedge:
				flags |= OB_WEDGE_BOND;
				beginIdx = endIdx;
				endIdx = swapIdx;
				break;
				case Bond::Hash:
				flags |= OB_HASH_BOND;
				break;
				case Bond::InvertedHash:
				flags |= OB_HASH_BOND;
				beginIdx = endIdx;
				endIdx = swapIdx;
				break;
				default:
				break;
			}
			obmol.AddBond(beginIdx, endIdx, bond->bondOrder(), flags);

			}
			obmol.EndModify();
		}
		}

		return obmol;

	}


	Molecule* convertFromMol(OBMol obmol)
	{
	// Create a new molecule
		Molecule* mol = new Molecule();
		mol->setPos(QPointF(0,0));

		//       if(dynamic_cast<MolScene*>(scene) && dynamic_cast<MolScene*>(scene)->autoAddHydrogen())
		//         obmol->AddHydrogens();
		//       else
		//         obmol->DelHydrogens();
		//         cerr << "mol " << "x: " << mol->pos().x() << " y: " << mol->pos().y() << "\n";

		// Initialize normalization factor
		//       qreal factor = 1;
		// molfile.GetInternalCoord(0,0,0);

		// Add atoms one-by-ons
		for (unsigned int i = 1; i <= obmol.NumAtoms();i++)
		// 	FOR_ATOMS_OF_MOL(obatom,obmol)
		{
		OpenBabel::OBAtom *obatom = obmol.GetAtom(i);
		//  			scene->addRect(QRectF(atom->GetX(),atom->GetY(),5,5));
		//           Atom* atom =
		mol->addAtom(Molsketch::number2symbol(obatom->GetAtomicNum()),QPointF(obatom->x()*40,obatom->y()*40), false);

		}

		// Add bonds one-by-one
		/// Mind the numbering!
		for (unsigned int i = 0; i < obmol.NumBonds(); ++i) {
		// Loading the OpenBabel objects
		OpenBabel::OBBond *obbond = obmol.GetBond(i);
		OBAtom *a1 = obbond->GetBeginAtom();
		OBAtom *a2 = obbond->GetEndAtom();

		// Creating their internal counterparts
		Atom* atomA = mol->atomAt(QPointF(a1->x()*40,a1->y()*40));
		Atom* atomB = mol->atomAt(QPointF(a2->x()*40,a2->y()*40));
		Bond* bond  = mol->addBond(atomA,atomB,obbond->GetBondOrder());

		// Set special bond types
		if (obbond->IsWedge())
			bond->setType( Bond::Wedge );
		if (obbond->IsHash())
			bond->setType( Bond::Hash );
		}

		return mol;
	}
}